﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using ProjectBase.Core;
using ProjectBase.Mvc.Views;
using ProjectBase.Mvc.Models;
using ProjectBase.Mvc.Controllers;

using System.Collections.Specialized;
using System.Web.Mvc;
using $prjsn$.Business;
using $prjsn$.Business.Services;

namespace $safeprojectname$.Core.Mvc
{
    [TestClass]
    public class SmartBinder_CollectionTest : EntityTestBase<TranslatorFacade>
    {
        const int TestTranslatorId1 = 1;
        const int TestTranslatorId2 = 2;
        const int TestTranslatorId3 = 3;
        const int TestTranslatorId4 = 4;
        const int TestUserId = 1;

        [TestMethod]
        public void BindCollections()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();

            var formatProvider = CultureInfo.GetCultureInfo("en-us");

            var nameValueCollection = FillValueProviderWithCollections(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertCollections(entity, formatProvider);
        }
        [TestMethod]
        public void BindIntoExistingCollection()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();

            var formatProvider = CultureInfo.GetCultureInfo("en-us");
            var nameValueCollection = FillValueProviderWithCollections(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();
            entity.Translators.Add(Facade.GetById(2));

            binder.Bind(entity, valueProvider.ToContainer());

            AssertCollections(entity, formatProvider);
        }

        //[TestMethod]
        //public void BindCollectionWithNotExistingEntity()
        //{
        //    var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();

        //    var formatProvider = CultureInfo.GetCultureInfo("en-us");
        //    var nameValueCollection = FillValueProviderWithCollections(formatProvider);
        //    // key which does not belong to entity
        //    nameValueCollection.Add("Translator", int.MaxValue.ToString(formatProvider));
        //    var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);


        //    var entity = new DummyBindingEntity();

        //    binder.Bind(entity, valueProvider);

        //    AssertCollections(entity, formatProvider);
        //    Assert.IsTrue(Messages.IsNotEmpty());
        //}

        #region protected
        static NameValueCollection FillValueProviderWithCollections(CultureInfo formatProvider)
        {
            var nameValueCollection = new NameValueCollection();

            nameValueCollection.Add("Translators", TestTranslatorId1.ToString(formatProvider));
            nameValueCollection.Add("Translators", TestTranslatorId2.ToString(formatProvider));
            nameValueCollection.Add("Translators", TestTranslatorId3.ToString(formatProvider));
            nameValueCollection.Add("Translators", TestTranslatorId4.ToString(formatProvider));
            nameValueCollection["Users"] = TestUserId.ToString(formatProvider);

            return nameValueCollection;
        }

        static void AssertCollections(DummyBindingEntity entity, CultureInfo formatProvider)
        {
            Assert.IsTrue(entity.Users.IsNotEmpty(), "collection Users cannot be null nor empty");
            Assert.IsTrue(entity.Translators.IsNotEmpty(), "collection Translators cannot be null nor empty");

            Assert.IsTrue(entity.Users.Count == 1, "collection Users should have 1 item");
            Assert.IsTrue(entity.Translators.Count == 4, "collection Translators should have 4 items");

            Assert.AreEqual(entity.Users.ElementAt(0).ID, TestUserId, "User ID does not match expected value '{0}'", TestUserId.ToString(formatProvider));
            Assert.IsTrue(entity.Translators.Any(t => t.ID.Equals(TestTranslatorId1))
                , "Translator ID does not match expected value '{0}'", TestTranslatorId1.ToString(formatProvider));
            Assert.IsTrue(entity.Translators.Any(t => t.ID.Equals(TestTranslatorId2))
                , "Translator ID does not match expected value '{0}'", TestTranslatorId2.ToString(formatProvider));
            Assert.IsTrue(entity.Translators.Any(t => t.ID.Equals(TestTranslatorId3))
                , "Translator ID does not match expected value '{0}'", TestTranslatorId3.ToString(formatProvider));
            Assert.IsTrue(entity.Translators.Any(t => t.ID.Equals(TestTranslatorId4))
                , "Translator ID does not match expected value '{0}'", TestTranslatorId4.ToString(formatProvider));
        }
        #endregion protected

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        [TestInitialize]
        public override void MyTestInitialize()
        {
            base.MyTestInitialize(); // Use TestInitialize to run code before running each test
        }

        [TestCleanup]
        public override void MyTestCleanup()
        {
            base.MyTestCleanup(); // Use TestCleanup to run code after each test has run
        }
        #endregion
    }
}
